package cn.net.xyan.easy.webapp.base.support;

import cn.net.xyan.easy.gwt.client.model.SortOrder;
import cn.net.xyan.easy.spring.core.utils.JsonHelper;
import org.springframework.core.MethodParameter;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.util.LinkedList;
import java.util.List;

/**
 * Created by zarra on 16/3/10.
 */
public class PageableResolver implements HandlerMethodArgumentResolver {

    PageableHandlerMethodArgumentResolver originResolver = new PageableHandlerMethodArgumentResolver();
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.getNestedParameterType().isAssignableFrom(Pageable.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        String input = nativeWebRequest.getHeader(cn.net.xyan.easy.gwt.client.model.Pageable.HEADKEY);
        try {
            if (input == null || input.length() == 0) {
                throw new NullPointerException();
            }
            cn.net.xyan.easy.gwt.client.model.Pageable p = JsonHelper.objectMapper().readValue(input, cn.net.xyan.easy.gwt.client.model.Pageable.class);
            PageRequest pageRequest ;
            Sort sort = null;
            if (p.getSortOrders().size()>0) {
                List<Sort.Order> orders = new LinkedList<>();
                for (SortOrder sortOrder : p.getSortOrders()) {
                    Sort.Order order;
                    if (SortOrder.ASC.equals(sortOrder.getDirection())) {
                        order = new Sort.Order(Sort.Direction.ASC, sortOrder.getColumn());
                    } else {
                        order = new Sort.Order(Sort.Direction.DESC, sortOrder.getColumn());
                    }
                    orders.add(order);
                }
                sort = new Sort(orders);
            }

            if (sort!=null)
                pageRequest = new PageRequest(p.getPage(),p.getPageSize(),sort);
            else
                pageRequest = new PageRequest(p.getPage(), p.getPageSize());

            return pageRequest;
        }catch (Throwable e){
            return originResolver.resolveArgument(methodParameter, modelAndViewContainer, nativeWebRequest, webDataBinderFactory);
        }
    }
}
